<?php

/**
 * This class covers all catalog functionality. Searching, borrowing 
 * and requesting books
 *
 * @author Honza
 */
class ContentCatalog implements IMainBodyWithInteraction {

  const TITLE_AUTHOR = 1; // ID of search by title/author form
  const GENRE = 2;        // ID of search by genre form

  private $genre;         // selected genre (if search by genre form was created)
  private $search;        // value of search field
  private $in;            // 1 - seearch by author, 2 - search by genre
  private $showTable;     // if table and forms should be shown
  private $condition;     // condition piece of SQL query used for table content
  private $auth;          // singleton class representing logged user

  public function __construct() {
    // get Auth instance
    $this->auth = Auth::getInstance();
  }

  public function applyForm($formID = NULL) {
    if ($formID == self::TITLE_AUTHOR) {
      // search by title/author was submited
      $this->search = addslashes($_POST['search']);
      $this->in = $_POST['in'];
      switch ($this->in) {
        case 1:
          // author
          $this->condition = 'where lower(concat(name, \' \', surname)) like \'%' . strtolower($this->search) . '%\'';
          break;
        case 2:
          // title
          $this->condition = 'where lower(title) like \'%' . strtolower($this->search) . '%\'';
          break;
      }
    }

    if ($formID == self::GENRE) {
      // search by genre was submited
      $this->genre = $_POST['genre'];
      $this->condition = 'where id_genre = ' . $this->genre;
    }
  }

  public function getContent() {
    $this->showTable = true;
    $content = '<h2>Catalog</h2>';

    if (isset($_GET['a'])) {
      //if there is some action in URL, serve it.
      $content .= $this->action();
    }

    if ($this->showTable) {
      // if we want to see a table we always want to see a search form
      $formID = $this->getSubmitedForm();
      if ($formID > 0) {
        //if the form was submitted, serve this submission
        $this->applyForm($formID);
      }

      // add forms and table to page
      $content .= $this->getForm(self::TITLE_AUTHOR);
      $content .= $this->getForm(self::GENRE);
      $content .= $this->getTable();
    }

    return $content;
  }

  public function getForm($formID = NULL, $error = NULL) {
    if ($formID == self::TITLE_AUTHOR) {
      // create html for search by title or author form
      $f = new Form();
      $f->startForm('self', 'post', NULL, array("class" => "form_settings"));
      $f->addDescription('Searching');
      $f->addLabel('Search', 'search')->addInput('text', 'search', $this->search);
      $sql = 'select * from ' . TBL_GENRES;

      $in = array();
      $in[0] = array('id' => 2, 'text' => 'Title');
      $in[1] = array('id' => 1, 'text' => 'Author');
      $f->addLabel('By', 'in')->addSelectionBox('in', $in, 'text', 'id', $this->in);
      $f->addLabel('&nbsp', 'findSubmit')->addInput('submit', 'findSubmit', 'Search', array("class" => "submit"));
      $f->endForm();

      $form .= $f->getForm();
    }

    if ($formID == self::GENRE) {
      // create html for search by genre
      $f = new Form();
      $f->startForm('self', 'post', NULL, array("class" => "form_settings"));

      // selects all genres to show them in combo box
      $sql = 'select * from ' . TBL_GENRES;
      
      // add all form element
      $f->addDescription('Searching by genre');
      $f->addLabel('Genre', 'genre')->addSelectionBox('genre', DB::sql($sql), 'name', 'id_genre', $this->genre);
      $f->addLabel('&nbsp', 'genreSubmit')->addInput('submit', 'genreSubmit', 'Search', array("class" => "submit"));
      $f->endForm();

      $form .= $f->getForm();
    }

    return $form;
  }

  public function getSubmitedForm() {
    if (isset($_POST['findSubmit'])) {
      // search by title/author was submited
      return self::TITLE_AUTHOR;
    }

    if (isset($_POST['genreSubmit'])) {
      // search by genre was submited
      return self::GENRE;
    }

    return -1;
  }

  public function getTable($tableID = NULL) {
    // join tables: books, authors, genres and append the where condition
    // created in applyForm method
    $sql = 'select id_book, title, concat(name, \' \', surname) as autor from ' . TBL_BOOKS . '';
    $sql .= ' join ' . TBL_AUTHORS_BOOKS . ' using (id_book)';
    $sql .= ' join ' . TBL_AUTHORS . ' using (id_author)';
    $sql .= ' join ' . TBL_GENRES_BOOKS . ' using (id_book)';
    $sql .= ' ' . $this->condition;
    $sql .= ' order by title';

    // send query to DB
    $result = DB::sql($sql);

    if (empty($result)) {
      // retult is empty - no book with given criteria
      return '<p>No books found.</p>';
    }

    $lastID = -1;

    $table = '<table>'; //table
    
    $table .= '<tr>';  // table header
    $table .= '<th>Title</th><th>Author</th><th>Detail</th>';

    if ($this->auth->hasAuthority(ROLE_USER)) {
      // if a user is logged he can borrow a book (show next column)
      $table .= '<th>Borrow a book</th>';
    }
    $table .= '</tr>'; // end of table header

    foreach ($result as $row) {
      // create table row for each book that meets criteria
      $bookID = $row['id_book'];

      if ($bookID != $lastID) {
        $lastID = $bookID;
        $table .= '<tr>'; // table row
        $table .= '<td>' . $row['title'] . '</td>';
        $table .= '<td>' . $row['autor'] . '</td>';
        $table .= '<td><a href="index.php?where=catalog&a=detail&ida=' . $bookID . '">Detail</a></td>';
        if ($this->auth->hasAuthority(ROLE_USER)) {
          // if a user is logged he can borrow a book... action: borrow
          $table .= '<td><a href="index.php?where=catalog&a=borrow&ida=' . $bookID . '">Borrow</a></td>';
        }
        $table .= '</tr>'; // end of table row
      }
    }
    
    $table .= '</table>';  // end of table
    return $table;
  }

  public function action() {
    
    if ($_GET['a'] == 'require') {
      // all book prints are booked. Add user to waiting queue
      if ($this->auth->hasValidReaderCard()) {
        // he can require a book only if he has valid library card
        $bookPrintID = addslashes($_GET['ida']);
        $identity = $this->auth->getIdentity();
        $userID = $identity['id'];

        // get bookID by bookPrintID
        $sql = 'select * from ' . TBL_BOOK_PRINTS . ' where id_book_print = ' . $bookPrintID;
        $bookprint = DB::sql($sql);
        $bookID = $bookprint[0]['id_book'];

        // create entry in requests table
        $sql = 'insert into ' . TBL_REQUESTS . " values (0, $userID, $bookID, CURDATE(), 'platný')";
        DB::sql($sql);
      } else {
        //hasnt got valid lib card
        $returnText .= '<p class="error">You don´t have library card. You can´t reserve any book</p>';
      }
    }
    
    if ($_GET['a'] == 'reserve') {
      // bookprint is free, user can reserve it
      if ($this->auth->hasValidReaderCard()) {
        // he can reserve a book only if he has valid library card
        $bookPrintID = addslashes($_GET['ida']);
        $identity = $this->auth->getIdentity();
        $userID = $identity['id'];
        
        // check if the book has not been reserved
        $sql = 'select * from ' . TBL_BORROWINGS . " where id_book_print = '$bookPrintID' and date_of_returning is null";
        $result = DB::sql($sql);
        
        if ($result) {
          $returnText .= '<p class="error">This book print is already reserved</p>';
        } else {
          // the book is still free, create entry in borrowings table
          $sql = 'insert into ' . TBL_BORROWINGS . " values (0, $bookPrintID, $userID, null,null,null,0)";
          DB::sql($sql);
        }
      } else {
        //hasnt got valid library card
        $returnText .= '<p class="error">You don´t have library card. You can´t reserve any book</p>';
      }
    }

    
    if ($_GET['a'] == 'borrow') {
      // user wants to borrow a book. We will list him all bookprints of the book.
      $this->showTable = false;

      if (!$this->auth->hasAuthority(ROLE_USER)) {
        // user has to be logged in
        $returnText .= ACCESS_DENIED;
      } else {

        $bookID = addslashes($_GET['ida']);

        // joins book_prints, books and locations tables and serches all bookprints
        // with given bookID
        $cols = TBL_BOOKS . '.title as book_title, ' . TBL_LOCATIONS . '.name as location_title, id_book_print';
        $sql = 'select ' . $cols . ' from ' . TBL_BOOK_PRINTS;
        $sql .= ' join ' . TBL_BOOKS . ' using (id_book)';
        $sql .= ' join ' . TBL_LOCATIONS . ' using (id_location)';
        $sql .= ' where id_book = ' . $bookID;

        $result = DB::sql($sql);
        if (empty($result)) {
          // A book has no bookprint or doesnt exist
          return '<p>No book prints</p>';
        }
        
        //show table of bookprints
        $table = '<table>'; // table
        $table .= '<tr>'; // table heared
        $table .= '<th>Title</th><th>Location</th><th>State</th><th>Borrow</th>';

        $table .= '</tr>'; // end of table header

        $isFree = false;
        foreach ($result as $row) {
          // for each bookprint that meets the criteria
          
          $bookPrintID = $row['id_book_print'];
          $table .= '<tr>'; // table row
          $table .= '<td>' . $row['book_title'] . '</td>';
          $table .= '<td>' . $row['location_title'] . '</td>';


          // is this bookprint borrowed?
          $sql = 'select * from ' . TBL_BORROWINGS . " where id_book_print = '$bookPrintID' and date_of_returning is null";

          if (DB::sql($sql)) {
            // it is borrowed
            $table .= '<td>Borrowed</td>';
            $table .= '<td>&nbsp;</td>';
          } else {
            // it is free
            $table .= '<td>Free</td>';
            $table .= '<td><a href="index.php?where=catalog&a=reserve&ida=' . $bookPrintID . '">Reserve</a></td>';
            $isFree = true;
          }

          $table .= '</tr>'; // end of table row
        }
        $table .= '</table>'; // end of table

        if (!$isFree) {
          // none of bookprints is free, offer user to enqueue to the waiting queue
          $returnText .= 'There is no free book print. Do you want to ';
          $returnText .= '<a href ="index.php?where=catalog&a=require&ida=' . $bookPrintID . '">enqueue</a>';
          $returnText .= ' to the waiting queue?';
        }

        $returnText .= $table;
      }
    }

    if ($_GET['a'] == 'detail') {
      //show book detail - use ContentBook class
      $this->showTable = false;
      $bookDetail = new ContentBook($_GET['ida']);
      return $bookDetail->getContent();
    }
    
    return $returnText;
  }

}

?>
